/* 
   Copyright 2012 Ryne Okimoto

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */

package recipe;

import java.util.ArrayList;

/**
 * Class - RecipeData
 * Description - Abstract representation of a recipe
 * 
 * @author Ryne Okimoto
 */

public class RecipeData {

	// Class data
	private String recipeName = null;
	private String imageFileName = null;
	private String category = null;

	private String ingredients = null;
	private String instructions = null;
	private String stringOfTags = null;
	private ArrayList<Ingredient> listOfIngredients;
	
	// TODO alternative implementation for tags 
	// private ArrayList<String> listOfTags;
	
	/**
	 * Default constructor
	 */
	public RecipeData(){
		recipeName = "";
		imageFileName = "";
		ingredients = "";
		instructions = "";
		category = "";
		stringOfTags ="";
		listOfIngredients = new ArrayList<Ingredient>();

	} // constructor
	
	/**
	 * Method - getRecipeName
	 * Description - getter for recipeName
	 * @return String
	 */
	public String getRecipeName(){
		return recipeName;
	}
	
	/**
	 * Method - setRecipeName
	 * Description - setter for recipeName
	 * @return void
	 */
	public void setRecipeName(String recipeName){
		this.recipeName = recipeName;
	}
	
	/**
	 * Method - getImageFileName
	 * Description - getter for imageFileName
	 * @return String
	 */
	public String getImageFileName(){
		return imageFileName;
	}
	
	/**
	 * Method - setImageFileName
	 * Description - setter for imageFileName
	 * @param imageFileName
	 */
	public void setImageFileName(String imageFileName){
		this.imageFileName = imageFileName;
	}
	
	/**
	 * Method - getCategory
	 * Description - getter for category
	 * @return String
	 */
	public String getCategory(){
		return this.category;
	}
	
	/**
	 * Method - setCategory
	 * Description - setter for category
	 * @param category
	 */
	public void setCategory(String category){
		this.category = category;
	}
	
	/**
	 * Method - addIngredient
	 * Description - adds an ingredient to the list of ingredients
	 * @param name
	 * @param amount
	 * @param unit
	 * @return boolean
	 */
	public boolean addIngredient(String name, String amount, String unit){
		boolean isUnitOK = Ingredient.validateUnit(unit);
		double amountValue = Ingredient.parseAmount(amount);
		
		if(isUnitOK && amountValue > 0){
			listOfIngredients.add(new Ingredient(name, amount, unit));
		}
		
		return isUnitOK && amountValue > 0;
	}
	
	/**
	 * Method - getListOfIngredients
	 * Description - Returns a list containing all ingredients
	 * @return ArrayList<Ingredient>
	 */
	public ArrayList<Ingredient> getListOfIngredients(){
		return listOfIngredients;
	}
	
	public String getListOfIngredientsAsString(){
		StringBuilder temp = new StringBuilder();
		for(int i = 0; i < listOfIngredients.size(); i++){
			temp.append(listOfIngredients.get(i));
			if(i != (listOfIngredients.size() - 1)){
				temp.append("\n");
			}
		}
		return temp.toString();
	}
	
	/**
	 * Method - setListOfIngredients
	 * Description - Takes a string that consists of ingredients separated by newlines
	 * and splits it into separate ingredient strings.  The ingredient strings are 
	 * split into the name, amount, and unit. The ingredient is added to the list. 
	 * @param ingredients_string
	 * @return void
	 */
	public void setListOfIngredients(String ingredients_string){
		String[] ingredients_array = ingredients_string.split("\\n");
		String[] temp_ingredient = null;
		StringBuilder name = new StringBuilder();
		
		// Reset to blank list
		listOfIngredients = new ArrayList<Ingredient>();
		
		for(int i = 0; i < ingredients_array.length; i++){
			temp_ingredient = ingredients_array[i].split(" ");
			for(int j = 2; j < temp_ingredient.length; j++){
				name.append(temp_ingredient[j]);
				if(j != temp_ingredient.length - 1){
					name.append(" ");
				}
			}
			this.addIngredient(name.toString(), temp_ingredient[0], temp_ingredient[1]);
			name = new StringBuilder();
		}
	}
	
	/**
	 * Method - getIngredients
	 * Description - getter for ingredients
	 * @return String
	 */
	public String getIngredients(){
		return ingredients;
	}
	
	/**
	 * Method - setIngredients
	 * Description - setter for ingredients
	 * @return void
	 * @param String
	 */
	public void setIngredients(String ingredients){
		this.ingredients = ingredients;
	}
	
	/**
	 * Method - getInstructions
	 * Description - getter for instructions
	 * @return String
	 */
	public String getInstructions(){
		return instructions;
	}
	
	/**
	 * Method - setInstructions
	 * Description - setter for instructions
	 * @return void
	 * @param String
	 */
	public void setInstructions(String instructions){
		this.instructions = instructions;
	}
	
	/**
	 * Method - getTags
	 * Description - getter for tags
	 * Notes - Initial implementation using a String not a list
	 * @return String
	 */
	public String getTags(){
		return this.stringOfTags;
	}
	
	/**
	 * Method - setTags
	 * Description - setter for tags
	 * Notes - Initial implementation using a String
	 * @param stringOfTags
	 */
	public void setTags(String stringOfTags){
		this.stringOfTags = stringOfTags;
	}
	
	/**
	 * convertUnits
	 * Description: Method to convert units from metric to standard and standard to metric
	 * @param none
	 * @return True - returns if the conversion completes successfully
	 * @return False - returns if there is a conversion error
	 */
	public boolean convertUnits(){
		boolean conversionOK = true;
		
		for(int i = 0; i < listOfIngredients.size(); i++){
			if(listOfIngredients.get(i).convertUnit() == 0){
				conversionOK = false;
			}
		}
		
		return conversionOK;
	} // convertUnits
	
	/**
	 * Method - scaleAmount
	 * Description - Adjusts the amount of ingredients based on a multiplier
	 * @param scaleFactor
	 * @return True - Returns if the operation completes successfully
	 * @return False - Returns if the operation fails 
	 */
	public boolean scaleAmount(int scaleFactor){
		boolean scaleOK = true;
		
		if(scaleFactor > 0){
			for(int i = 0; i < listOfIngredients.size(); i++){
				// TODO bug if one ingredient isn't able to be scaled, others will
				if(listOfIngredients.get(i).scaleAmount(scaleFactor) == 0){
					scaleOK = false;
				}
			}
		}
		
		return scaleOK;
	} // scaleAmount
	
} // class
